<?php 

namespace Api\Controller\V2;

use Api\Event\CacheEvent;

class LuckyboxController extends V2BaseController
{

    protected $activity;
    /**
     * 幸运宝箱
     * @return [type] [description]
     */
    public function index()
    {
        $this->checkLogin();
        // 参数判定
        if (!request('uuid')){
            error(500, 'Uuid不能为空');
        }

        // 读取活动信息 读取配置
        // 活动状态<未开始, 已结束>
        $this->getActiviyInfo();
        // print_r($this->activity);
        // uuid 存在判定
        $this->checkUuid();
        // 抽奖次数上限判断
        $this->checkHourTimes();
        // 生成中奖项目和动态概率计算
        $this->setdynamProbability();        
        // print_r($this->activity);

        // 中奖判定 
        $key = roll($this->activity['rateItem']);

        // 中奖项目处理
        $key && $res = $this->handlePrizeItem($key);

        empty($res) ? $this->lose() : $this->win();
    }

    /**
     * 中奖返回
     * @return [type] [description]
     */
    protected function win()
    {
        $result = [
            'win' => 1,
            'prize' => $this->prize,
        ];
        success('', $result);
    }

    /**
     * 未中奖返回
     * @return [type] [description]
     */
    protected function lose()
    {
        $result = [
            'win' => 0,
        ];
        success('未中奖', $result);
    }

    /**
     * 读取活动和配置
     * 并且对配置进行格式化
     */
    protected function getActiviyInfo()
    {
        $cache = CacheEvent::instance(0);
        $date = date('Y-m-d H:i:s');
        $key   = 'IMBA.LOTTERY.LUCYBOX.'.date('Ymd');
        $activity = $cache->get($key);
        $activity = json_decode($activity, true);
        if (!$activity){
            $map = [
                'start_time' => ['elt', $date],
                'end_time' => ['gt', $date],
            ];
            $activity = service('Activity/ActivityLuckybox')->where($map)->find();
            $cache->setex($key, 3600*24, json_encode($activity));
        }
        if (!$activity || $activity['status'] != 1){
            error(90000); // 活动尚未开始或者已经结束
        }

        $this->activity = $activity;
    }

    /**
     * 检查并且设置uuid使用
     * @return [type] [description]
     * 3-5ms
     */
    protected function checkUuid()
    {
        $uuid  = request('uuid');
        if (!$uuid){
            return $this->lost();
        }
        $cache = CacheEvent::instance(0);
        $key = 'IMBA.LOTTERY.LUCYBOX.UUID.'.date('Ymd');
        if (!$cache->sismember($key, $uuid)){
            $cache->sadd($key, $uuid);
            unset($cache);
        }else{
            $this->lose();
        }
    }

    /**
     * 检查用户抽奖次数(1小时内)
     * @author liubo <liubo@ilongyuan.com.cn>
     */
    protected function checkHourTimes() {
        $hour_times = 5; // 单个用户每小时抽奖次数上限
        $uid  = request('uid');
        if (!$uid){
            return $this->lost();
        }
        $cache = CacheEvent::instance(0);
        $key = 'IMBA.LOTTERY.LUCYBOX.UID.'.date('YmdH');
        $times = $cache->zScore($key, $uid);
        if (empty($times) || $times < $hour_times) {
            $cache->zIncrBy($key, 1, $uid);
            unset($cache);
        } else {
            $this->lose();
        }
    }

    /**
     * 生成动态的概率
     * @return [type] [description]
     */
    protected function setdynamProbability()
    {
        $cache = CacheEvent::instance(0);
        $key = 'IMBA.LOTTERY.LUCYBOX.WINITEM.'.date('YmdH');
        $hourwins = $cache->hgetall($key);
        unset($cache);

        foreach ($this->activity['config'] as $key => $itemConfig) {
            $probability = $itemConfig['probability'] ?: 0;
            if ($probability==0){
                continue;
            }
            if ($itemConfig['hourNumber'] && isset($hourwins[$key]) && $hourwins[$key] > 0){
                $left = $hourwins[$key] < $itemConfig['hourNumber'] ? $itemConfig['hourNumber'] - $hourwins[$key] : 0;
                $probability *= $left/$itemConfig['hourNumber'];
            }
            if ($probability==0){
                continue;
            }
            $this->activity['rateItem'][$key] = $probability;
        }
    }

    /**
     * 处理中奖项目
     * @return bool [返回结果 失败则按照未中奖结算]
     */
    protected function handlePrizeItem($key)
    {
        $prize = $this->activity['config'][$key];
        $type = $prize['type'];
        switch ($type) {
            case 'money':
                $text = sprintf($prize['text'][array_rand($prize['text'])], $prize['amount']);
                $this->prize = [
                    'type' => 1,
                    'avatar' => $prize['image'],
                    'text' => $text,
                    'money' => $prize['amount'],
                    'href' => 'ly66play://66play?type=money_record',
                ];
                $params = [
                    'uid' => intval(request('uid')),
                    'money' => intval($prize['amount']),
                    'activity_id' => $this->activity['_id'],
                    'activity_title' => $this->activity['title'],
                ];
                event('LocalClient')->doAsyncRequest('add_coin_activity', $params);
                break;
            case 'goods':
                $goods_id = $prize['id'];

                $params = [
                    'uid' => intval(request('uid')),
                    'id' => intval($goods_id),
                ];
                $pay_result = event('LocalClient')->doRequest('pay_mall_activity', $params);
                if ($pay_result && $pay_result['code'] == 200) {
                    $goods = $pay_result['data']['goods'];
                }
                if (empty($goods)) {
                    return false;
                }

                $text = sprintf($prize['text'][array_rand($prize['text'])], $goods['name']);
                $this->prize = [
                    'type' => 2,
                    'avatar' => $goods['thumb'],
                    'text' => $text,
                    'money' => $goods['price'],
                    'href' => 'ly66play://66play?type=mine_goods&id='.$goods['id'],
                ];
                break;
            case 'threads':
                $threads = $prize['photos'][array_rand($prize['photos'])];

                $text = $prize['text'][array_rand($prize['text'])];
                $this->prize = [
                    'type' => 3,
                    'avatar' => $threads['image'],
                    'text' => $text,
                    'money' => 0,
                    'href' => 'ly66play://66play?type=threads&id='.$threads['id'],
                ];
                break;
            default:
                return false;
        }
        $redis_key = 'IMBA.LOTTERY.LUCYBOX.WINITEM.'.date('YmdH');
        $cache = CacheEvent::instance(0);
        $hourwins = $cache->hget($redis_key, $key);
        $cache->hset($redis_key, $key, intval($hourwins) + 1);
        unset($cache);
        return true;
    }
}
